import java.io.DataOutputStream;
import java.io.PrintStream;
import java.util.Iterator;

public class IRProducer {

	//private static FunctionStruct currentFunction=null;
	
	private static boolean functionWriteOpen=false;
	
	private boolean tempMode=false;
	
	public String tempStr="";
	
	public void setTempMode(boolean mode){
		tempMode=mode;
	}
	
	private static String outerDeclear="";
	
//	public FunctionStruct getCurrentFunction(){
//		return producer.currentFunction;
//	}
//
//	public void setCurrentFunction(FunctionStruct fs){
//		producer.currentFunction=fs;
//	}
	
	public static IRProducer getProducer(){
		return producer;
	}

	private static IRProducer producer=new IRProducer();
	
//	public void output(String s){
//		if(currentFunction!=null){
//		// System.out.println(currentFunction.functionName+":"+s);
//			if(tempMode){
//				if(tempStr.equals("")){
//					tempStr+=s;
//				}else{
//					tempStr+="\r\n";
//					tempStr+=s;
//				}
//				return;
//			}
//		 currentFunction.functionStmts+=s;
//		 currentFunction.functionStmts+="\r\n";
//		}
//
//	}
	
//	public void declear(String d){
//		if(currentFunction==null){
//			outerDeclear+=d;
//			outerDeclear+="\r\n";
//			//System.out.println("outer:"+d);
//		}else{
//			 currentFunction.functionDeclear+=d;
//			 currentFunction.functionDeclear+="\r\n";
//		}
//
//	}
	
	public static void printfCode(PrintStream out){
		//System.setOut(out);
		out.println(";define variables");
		out.println(".Data");
		out.println("@_float0@ DD ? ;This is a special variable to contain float");
		out.println("@_float1@ DD ? ;This is a special variable to contain float");
		out.println("@_float2@ DD ? ;This is a special variable to contain float");
		out.println("@_paramPass0@ DQ ?;This is special variable to pass parameter");
		out.println("@_paramPass1@ DQ ?;This is special variable to pass parameter");
		out.println("@_paramPass2@ DQ ?;This is special variable to pass parameter");
		out.println(outerDeclear);
		out.println(";code section");
		out.println(".Code");
		
		Iterator<FunctionStruct> it=FunctionDefine.getFunctionDefine().getIterator();
		while(it.hasNext()){
			FunctionStruct fs=it.next();
			if(fs.functionName.equals("main")){
				out.println(";Main Function");
				out.println("@Main FRAME");
				out.print(fs.functionDeclear);
				out.print(fs.functionStmts);
				out.println("ret");
				out.println("endF");
			}
			else{
				Iterator<VariableStruct> itvs=fs.list.iterator();
				String variables="";
				while(itvs.hasNext()){
					variables+="@"+itvs.next().name;
					variables+=",";
				}
				if(variables.length()!=0){
				variables=variables.substring(0,variables.length()-1);
				}
				out.println(";define:"+fs.functionName);
				out.println("func@"+fs.functionName+" FRAME "+variables);
				out.print(fs.functionDeclear);
				out.print(fs.functionStmts);
				out.println("endF");
				out.println(";define end");
			}
			out.println("");


		}
		out.println(";Program entry");
		out.println("Start:");
		out.println("Invoke @Main");
		out.println("Ret");
	}
	
	public void beginWirteFunction(FunctionStruct fs){
		//添加function
		if(functionWriteOpen){
			System.err.println("System error in functionWriteOpen");
		}else{
			functionWriteOpen=true;
		}
		FunctionDefine.getFunctionDefine().add(fs);
		LocalSymbol.getCurrent().setCurrentFunction(fs);
	    ImcProducer.getProducer().setCurrentFunction(fs); 
	}
	
	public void endWriteFunction(){
		if(!functionWriteOpen){
			System.err.println("System error in functionWriteOpen");
		}else{
			functionWriteOpen=false;
		}
		LocalSymbol.getCurrent().setCurrentFunction(null);
		ImcProducer.getProducer().setCurrentFunction(null);
		
	}
}
